import { CoffeeOutlined, CommentOutlined, ContactsOutlined, MacCommandOutlined, MessageOutlined, SmileOutlined, TeamOutlined } from '@ant-design/icons';
import { useEventListener } from '@nsb/common-tools';
import { Flex, notification, Typography } from 'antd';
import React, { useCallback, useEffect, useMemo } from 'react';
import { createPortal } from 'react-dom';
import { useNavigate as _useNavigate, NavigateOptions, To, useLocation } from 'react-router';
import Lazy from './component/Lazy';
import { Default } from './component/SuspenseFallback/Default';
import { UserPermission } from './hooks/UserPermission';
import { useTranslation } from './i18n';
const { Text } = Typography;
export namespace Paths {

  /**
   * 全部路径的枚举
   *
   * @export
   * @enum {number}
   */
  export enum All {
    Root = '/',
    Login = '/login',
    Main = '/main',
    About = '/main/about',
    LocalWXContacts = '/main/local_contacts',
    LocalWXSessions = "/main/local_sessions",
    Logo = '/logo',
    LocalChat = "/main/local_chat",
    RemoteChat = "/main/remote_chat",
    DevTasks = '/main/dev_tasks',
    WXAccountManagement = "/main/account_management",
    WXContactsManagement = "/main/contact_management",
    WXSessionsManagement = "/main/session_management",
    WXMessagesManagement = "/main/message_management",
    Management = "/main/management"
  }

  /**
   * 路径对应名称
   *
   * @export
   * @return {Record<All, string>}  {Record<All, string>}
   */
  export function useNames(): Record<All, string> {
    const { t } = useTranslation();
    return useMemo(() => {
      const r: Record<All, string> = {
        [All.Root]: '',
        [All.Login]: '',
        [All.Main]: '',
        [All.About]: '关于',
        [All.Logo]: 'LOGO',
        [All.LocalWXContacts]: '本地联系人',
        [All.LocalWXSessions]: '本地会话',
        [All.LocalChat]: 'LocalChat',
        [All.DevTasks]: '任务队列',
        [All.Management]: '管理',
        [All.WXAccountManagement]: '账号管理',
        [All.WXSessionsManagement]: '会话管理',
        [All.WXContactsManagement]: '联系人管理',
        [All.WXMessagesManagement]: '消息管理',
        [All.RemoteChat]: 'RemoteChat'
      }
      return r;
    }, [t]);
  }

  export const Icons: Record<All, React.ReactNode> = {
    [All.Root]: void 0,
    [All.Main]: void 0,
    [All.About]: <SmileOutlined />,
    [All.Login]: void 0,
    [All.Logo]: void 0,
    [All.LocalWXContacts]: <ContactsOutlined />,
    [All.LocalWXSessions]: <CommentOutlined />,
    [All.LocalChat]: <MessageOutlined />,
    [All.DevTasks]: <CoffeeOutlined />,
    [All.WXAccountManagement]: <TeamOutlined />,
    [All.WXContactsManagement]: <ContactsOutlined />,
    [All.WXSessionsManagement]: <CommentOutlined />,
    [All.Management]: <MacCommandOutlined />,
    [All.WXMessagesManagement]: <MessageOutlined />,
    [All.RemoteChat]: <MessageOutlined />,
  }
  /**
   * 路径对应图标
   *
   * @export
   * @return {Record<All, React.ReactNode>}  {Record<All, React.ReactNode>}
   */
  export function useIcons(): Record<All, React.ReactNode> {
    return Icons
    // return useMemo(() => Icons, []);
  }

  /**
   * 路径对应的页面组件
   */
  export const Routes: Record<All, React.ComponentType | undefined> = {
    [All.Root]: void 0,
    [All.Main]: React.lazy(() => import('@/pages/main')),
    [All.About]: Lazy(() => import('@/views/About')),
    [All.Login]: () => <>login</>,
    [All.Logo]: Lazy(() => import('@/views/LogoView')),
    [All.LocalWXContacts]: Lazy(() => import('@/views/ContactsView')),
    [All.LocalWXSessions]: Lazy(() => import('@/views/SessionsView')),
    [All.LocalChat]: Lazy(() => import('@/views/ChatView')),
    [All.RemoteChat]: Lazy(() => import('@/views/ChatView')),
    [All.DevTasks]: Lazy(() => import('@/views/TasksView')),
    [All.WXAccountManagement]: Lazy(() => import('@/views/Management/AccountManagement')),
    [All.WXContactsManagement]: Lazy(() => import('@/views/Management/ContactManagement')),
    [All.WXSessionsManagement]: Lazy(() => import('@/views/Management/SessionManagement')),
    [All.WXMessagesManagement]: Lazy(() => import('@/views/Management/MessageManagement')),
    [All.Management]: undefined
  }


  /**
   * 对于异步加载的页面, 未加载完成时，显示Loadings的内容
   *
   * @type {{ [key in All]?: React.ReactElement[] }}
   */
  export const Loadings: { [key in All]?: React.ReactElement } = {
    [All.Main]: <Default />
  }

  /**
   * 访问一个路径需要的权限
   *    值 === undefined // 表示不需要登录也能访问
   *    值 === ""      表示访问此路径只需要登录
   *    值 === "A,B"   表示访问此路径需要A权限与B权限
   */
  export const Permissions: Record<All, string | undefined> = {
    [All.Login]: void 0,
    [All.Root]: void 0,
    [All.Main]: void 0,
    [All.About]: void 0,
    [All.Logo]: void 0,
    [All.LocalWXContacts]: void 0,
    [All.LocalWXSessions]: undefined,
    [All.LocalChat]: undefined,
    [All.DevTasks]: 'developing',
    [All.WXAccountManagement]: "",
    [All.WXContactsManagement]: "",
    [All.WXSessionsManagement]: "",
    [All.Management]: "",
    [All.WXMessagesManagement]: "",
    [All.RemoteChat]: ""
  }

  /**
   * 路由的嵌套关系表, 决定了路由页面呈现在谁的里面
   */
  export const Relations: { [key in All]?: All[] } = {
    [All.Root]: [
      All.Main,
      All.Login,
      
      All.WXSessionsManagement,
      All.WXContactsManagement,
      All.WXMessagesManagement,
      All.WXAccountManagement,
      All.RemoteChat,
    ],
    [All.Main]: [
      All.About
    ]
  }

  /**
   * 当无权限访问某页面时，将尽量跳转至可访问的页面
   */
  export const AccessDeniedFallbacks: Paths.All[] = [
    Paths.All.About,
  ]

  export interface PermissionChecker {
    (pathname?: string): boolean
  };

  export function usePermission(): PermissionChecker {
    const checker = UserPermission.use();
    return useCallback((pathname?: string) => checker(Permissions[pathname as All]), [checker])
  }

  export interface _NavigateFunction {
    (to: To, options?: NavigateOptions): boolean;
    (delta: number): boolean;
  }
  export function useNavigate(): _NavigateFunction {
    const { pathname } = useLocation();
    const navigate = _useNavigate();

    const hasPermission = usePermission();
    return useCallback((to: To | number, options?: NavigateOptions) => {
      const interruption = document.getElementsByTagName('nsb-exit-interruption').item(0)
      if (interruption) {
        if (!confirm(interruption.innerHTML))
          return true
      }
      if (typeof to === 'number') {
        navigate(to);
        return false;
      }

      const [next_pathname] = typeof to === 'string' ? to.split(/#|\?/) : [(to.pathname ?? pathname), to.search, to.hash];
      if (hasPermission(next_pathname)) {
        navigate(to, options);
        return false
      }
      notification.error({
        message: <NoPermission pathname={next_pathname} />,
        duration: 0
      })

      if (location.pathname !== Paths.All.Login && hasPermission(location.pathname))
        return false;

      const fallbackPath = AccessDeniedFallbacks.find(path => hasPermission(path))
      if (fallbackPath) {
        delete options?.state;
        navigate(fallbackPath, options);
        return false
      }
      return false;
    }, [hasPermission])
  }
  export function NoPermission({ pathname }: { pathname?: string }) {
    const permissions = Permissions[pathname as All]
    const names = Paths.useNames()
    const page_readable_name = names[pathname as All] || '相关页面';
    useEffect(() => {
      console.trace(`你没有权限访问${pathname}, require permission: ${permissions}`);
    }, [pathname, permissions])
    return (
      <Flex vertical>
        <Text type='secondary'>
          你没有权限访问
          <Text>
            {page_readable_name}
          </Text>
        </Text>
        <Text type='secondary'>
          页面:
          <Text>
            {pathname}
          </Text>
        </Text>
        <Text type='secondary'>
          相关权限：
          <Text>
            {permissions || "你必须先登录"}
          </Text>
        </Text>
      </Flex>
    )
  }
  export function useExitInterruption(enabled: boolean, text: string = '离开本界面将会丢失已编辑的内容，是否离开？') {
    useEventListener(window, 'beforeunload', e => e.returnValue = text, void 0, enabled)
    if (!enabled) return [void 0]
    const ele = React.createElement('nsb-exit-interruption', { style: { display: 'none', position: 'fixed' } }, text)
    const por = createPortal(ele, document.body)
    return [por] as const
  }
  export interface GenNavTabKey { (pathname: string, search: string, hash: string): string }
  export const defaultNavTabKey: GenNavTabKey = (pathname, search, hash) => {
    return pathname + search + hash
  }
  export const NavTabKeys: { [x in All]?: GenNavTabKey } = {
    // [All.Class_Detail]: (pathname, search) => pathname + search
  }
}

